## 9.7. procmail

If your CGI scripts send out email, `procmail` is a very handy tool to learn, but it is only available for Unix. If you are on a Unix system and you do not have it, you can download it from http://www.procmail.org. `procmail` is a filtering application that allows you to automatically process email based on virtually any criteria. It's not simple, of course; few powerful tools are. And again, like the other tools presented in this chapter, we won't be able to discuss it in great detail here. Instead, we'll look at a couple configurations that should handle your basic needs. If you want to learn more, you can find links to several useful resources including quick-start guides and FAQs at http://www.iki.fi/era/procmail/. Also, don't forget to review the manpage; most of these online resources assume you have done this already. You may not normally enjoy reading manpages, but the `procmail` man pages are very well written and include numerous examples.

In order to run `procmail`, you need to create two files in your home directory (or the home directory of the user whose mail you want to forward). The first file, .forward , is used by `sendmail` when it delivers mail to your account. That file should be set up to it to direct `sendmail` to run `procmail`, and `procmail` uses the .procmailrc file to process the message. It is possible to have `procmail` set up as the mail transport agent on your system, instead of `sendmail`; in that case, you do not need the .forward file. Check with your system administrator to see if this is the case.

Your .forward file needs to include only the following line:

>     "|IFS=' '&&exec /usr/local/bin/procmail -f-||exit 75 #YOUR_USERNAME"

All of the quotes are necessary, there is only one space between the single quotes, you must supply the full path to `procmail`, and you should of course replace `YOUR_USERNAME` with your own username (or something to make this line different from the line in other users' .forward files).

### 9.7.1. Autoreply from nobody

Now all we need to do is create a .procmailrc file. The .procmailrc file contains rules and a command to execute if the rule matches. In this example, we will create only one rule that sends an autoreply to all incoming messages. This would be handy if messages sent to the user that the web server runs as are not redirected. If your web server runs as a valid user named nobody, you could place this in nobody's home directory. Here is the .procmailrc file:

>     ## This is your email address
>     EMAIL_ADDRESS=nobody@your-domain.com

>     ## Uncomment and edit this line if sendmail isn't at /usr/lib/sendmail
>     #SENDMAIL=/path/to/sendmail

>     ## If we get a message, verify that it wasn't sent by a mail daemon
>     ## or isn't one of our marked messages. If not, then reply to it using
>     ## the contents of the autoreply.txt file as the body of the message
>     ## and mark the message by adding an X-Loop header.
>     :0 h
>     * !^FROM_DAEMON
>     * !^X-Loop: $EMAIL_ADDRESS
>     | ( formail -r -A"X-Loop: $EMAIL_ADDRESS"; \
>         cat "$HOME/autoreply.txt"            ) | $SENDMAIL -t

>     ## Throw away the messages we're not replying to
>     :0
>     /dev/null

We'll briefly review what this file does. For more detailed information, refer to one of the references listed earlier. First, it sets the `$EMAIL_ADDRESS` variable to the email address of the account receiving this mail. Next, it should specify the path to sendmail if it is something other than the path that `procmail` defaults to (typically either /usr/lib/sendmail or /usr/sbin/sendmail ). The remaining lines are rules.

All rules start with `:0`. The first rule also has an `h` option indicating that we are only interested in the message headers of the incoming message; its body will not be included in our reply. All the lines that begin with `*` are conditions. Basically, any message that doesn't look like it was generated by a daemon process (this includes bounced mail, mailing lists, etc.) and doesn't include an X-Loop header with our email address in it should be processed by this rule. We'll see why we check for this header in a moment.

The message is processed by piping the headers through `formail` , a helper application included with `procmail`. It constructs a reply to the given headers and adds an X-Loop header containing our email address. The reason for adding this to our replies and checking for it in incoming messages is to avoid endless loops. If our CGI script sends a message that bounces (because of an invalid email address, a full account, etc.) and comes back to us, and we automatically reply to it, our reply will also bounce. This could go on forever, but if we add an X-Loop header, that should be maintained within replies so we will know if we see it that we have already replied to this message and to not process another reply. The check for whether the message was generated by a daemon should actually prevent us from replying to a bounce, but the daemon check isn't foolproof, so the X-Loop check is a good way to be safe.

`formail` takes care of the headers for us, and then we `cat` the contents of the autoreply.txt file in our home directory. You should create a message in this file appropriate to your site, saying something to the effect that this email address is not used and providing an alternative email address to the recipient. The final results of both the headers and the body are piped to `sendmail,` which reads the headers and delivers our new reply.

The remaining rule in the file has no conditions. It catches all messages that are not processed by the preceding rule, in other words, all messages that are sent by daemons or that have already been replied to. These messages are simply discarded by moving them to /dev/null.

### 9.7.2. Forwarding to Another User

It is also possible to simply forward all messages to another user. There are better alternatives than `procmail` for doing this. Specifically, `sendmail` allows aliases to be created to redirect mail sent from one email address to another. However, if you cannot get your system administrator to create an alias for you, here is a .procmail file that forwards all incoming mail to another email address:

>     ## This is the email address to forward to
>     FORWARD_TO=webmaster@your-domain.com

>     ## Uncomment and edit this line if sendmail isn't at /usr/lib/sendmail
>     #SENDMAIL=/path/to/sendmail

>     ## Forward all messages
>     :0
>     ! $FORWARD_TO

As you can see, procmail provides you with a number of options for automatically processing email. In one of our examples earlier, we piped the headers of incoming messages through `formail`. We could have just as easily piped the headers, the body, or the whole message through a Perl script and thus be able to react to every email that arrives. For example, you might want to flag or delete a database record when mail you send to that user is returned as undeliverable. That's just one example; you can probably think of others specific to your site.

Copyright © 2001 O'Reilly & Associates. All rights reserved.